"""
des: 
author: 邵宁
date: 2022-08-17
"""
import glob
import os
import re
import sqlite3
import logging
from flask import Flask, request, redirect, send_file, g
from flask import Blueprint, make_response, jsonify, send_from_directory

from flask_cors import CORS

from util import path, db, msg_template, msg_manage
from session_event_function import git_src_from_gitee, release_rpm_source, download_file, download_file_spec, \
    generate_compatibility_report
import session_manage

logging.basicConfig(level=logging.INFO, format='[%(asctime)s] %(message)s', datefmt='%Y/%m/%d %H:%M:%S')

app = Flask(__name__)  # 在当前文件下创建应用
sess_man = session_manage.SessionListManage()


@app.route("/")  # 装饰器，url，路由
def index():  # 试图函数
    return redirect("/static/index.html")


@app.route('/load_session_list', methods=['POST'])
def load_session_list():
    user_token = request.json.get('user_token', '')
    session_list = db.get_session_list(user_token)
    session_list_data = [{
        "session_token": session_one[4],
        "date": session_one[2],
        "name": session_one[3],
        'info': session_one[6],
        "tag": session_one[7],
    } for session_one in session_list]
    msg = msg_template.MsgTemplateSessionList()
    msg.set_key_value("data", session_list_data[::-1])
    return msg.get_json()


@app.route('/session_delete', methods=['POST'])
def session_delete():
    user_token = request.json.get('user_token', '')
    session_token = request.json.get('session_token', '')
    session_path = db.get_session_path(session_token)
    db.session_delete(session_token)
    path.file_del(session_path)
    msg = msg_template.MsgTemplateSessionInit()
    msg.set_key_value("msg_type", "session_delete")
    msg.set_key_value("session_token", session_token)
    res_json = msg.get_json()
    return res_json


@app.route('/load_session_msg', methods=['POST'])
def load_session_msg():
    session_token = request.json.get('session_token', '')
    session_msg_tag = request.json.get('session_msg_tag', '')
    session_msg_tag_curr = db.get_session_msg_tag(session_token)
    session_name = db.get_session_name(session_token)
    msg = msg_template.MsgTemplateSessionMsg()
    if session_msg_tag_curr == session_msg_tag:
        msg.set_key_value("msg_change", "no")
        # return msg.get_json()
    msg.set_key_value("msg_change", "yes")
    msg.set_key_value("session_name", session_name)
    msg.set_key_value("session_token", session_token)
    msg_list = msg_manage.msg_read(session_token)
    msg.set_key_value("msg_list", msg_list[::-1])
    msg.set_key_value("session_msg_tag", session_msg_tag_curr)
    return msg.get_json()


@app.route('/get_spec_list_by_session_token', methods=['POST'])
def get_spec_list_by_session_token():
    session_token = request.json.get('session_token', '')
    session_path = f"static/session/{session_token}"
    spec_list = []
    for r, d, f in os.walk(session_path):
        for f_o in f:
            if f_o.endswith(".spec"):
                spec_list.append(os.path.join(r, f_o).lstrip(session_path).replace('\\', '/').lstrip('/'))
    spec_list = [{"value": s_o.lstrip('/'), "label": s_o} for s_o in spec_list]
    msg = msg_template.MsgTemplateForSpecList()
    msg.set_key_value("session_token", session_token)
    msg.set_key_value("data", spec_list)
    return msg.get_json()


@app.route('/get_spec_by_session_token', methods=['POST'])
def get_spec_by_session_token():
    session_token = request.json.get('session_token', '')
    spec_path = request.json.get('spec_path', '').lstrip('/').lstrip('\\')
    spec_path = os.path.join(f"static/session/{session_token}", spec_path)
    spec_content = []
    if os.path.exists(spec_path):
        with open(spec_path, "r", encoding="utf-8") as f:
            spec_str = "".join(f.readlines())
        spec_content = spec_str.split("\n")
    msg = msg_template.MsgTemplateForSPEC()
    msg.set_key_value("session_token", session_token)
    msg.set_key_value("data", spec_content)
    msg.set_key_value("data_str", spec_str)
    return msg.get_json()


@app.route('/get_file_str_with_session_token', methods=['POST'])
def get_file_str_with_session_token():
    session_token = request.json.get('session_token', '')
    file_path = request.json.get('file_path', '').lstrip('/').lstrip('\\')
    file_path = os.path.join(f"static/session/{session_token}", file_path)
    file_name = os.path.basename(file_path)
    msg = msg_template.MsgTemplateForSPEC()
    file_str = "文件读取失败：" + file_name
    if os.path.exists(file_path) and os.path.isfile(file_path):
        try:
            with open(file_path, "r", encoding="utf-8") as f:
                file_str = "".join(f.readlines())
        except UnicodeDecodeError:
            msg.set_key_value("status", 500)
            file_str = "文件读取失败：" + file_name + "为二进制文件"
    msg.set_key_value("session_token", session_token)
    msg.set_key_value("data", file_str)
    return msg.get_json()


@app.route('/save_file_str_with_session_token', methods=['POST'])
def save_file_str_with_session_token():
    session_token = request.json.get('session_token', '')
    save_type = request.json.get('save_type', '')
    file_path = request.json.get('file_path', '').lstrip('/').lstrip('\\')
    file_str = request.json.get('file_str', '')
    file_path = os.path.join(f"static/session/{session_token}", file_path)
    file_name = os.path.basename(file_path)
    msg_str = "文件写入失败：" + file_name
    if os.path.exists(file_path) and os.path.isfile(file_path):
        try:
            with open(file_path, "r", encoding="utf-8") as f:
                f.readlines()
            with open(file_path, "w", encoding="utf-8") as f:
                f.write(file_str)
            msg_str = "文件保存成功！"
        except UnicodeDecodeError:
            pass
    msg = msg_template.MsgTemplateForSPEC()
    msg.set_key_value("session_token", session_token)
    msg.set_key_value("msg_str", msg_str)
    return msg.get_json()


@app.route('/session_function_do', methods=['POST'])
def session_function_do():
    session_token = request.json.get('session_token', '')
    session_function = request.json.get('session_function', '')
    session_setting = {}
    if session_function == "session_init":
        msg = msg_template.MsgTemplateSessionInit()
        if session_token == "":
            path_session_one = path.init_session_path()
            session_token = os.path.basename(path_session_one)
            msg.set_key_value("msg_type", "session_init")
            msg.set_key_value("session_token", session_token)
        else:
            path_session_one = path.init_session_path(session_token)
            msg.set_key_value("msg_type", "session_init")
            msg.set_key_value("session_token", session_token)
            session_info_json = {
                "user_id": 0,
                "session_name": "新建会话",
                "session_token": session_token,
                "session_path": path_session_one,
                "session_info": "",
                "session_status": "初始化",
                "session_msg_tag": "0000",
            }
            if db.create_session(session_info_json):
                msg.set_key_value("msg_str", "会话初始化成功！")
            else:
                msg.set_key_value("status", 300)
                msg.set_key_value("msg_str", "会话初始化失败")
        return msg.get_json()
    elif session_function == "session_setting_write":
        msg_manage.setting_write(request.json.get("session_setting", {}), session_token)
        msg = msg_template.MsgTemplateSessionSetting()
        msg.set_key_value("msg_type", "session_setting_write")
        msg.set_key_value("session_token", session_token)
        msg.set_key_value("msg_str", "会话设置更新")
        return msg.get_json()
    elif session_function == "session_setting_read":
        msg = msg_template.MsgTemplateSessionSetting()
        msg.set_key_value("msg_type", "session_setting_read")
        msg.set_key_value("session_token", session_token)
        msg.set_key_value("msg_str", "会话设置读取")
        msg.set_key_value("data", msg_manage.setting_read(session_token))
        return msg.get_json()
    elif session_function == "git_src_from_gitee":
        req_json_para = {
            "session_token": session_token,
            "code_name": request.json.get('code_name', ''),
            "code_branch": request.json.get('code_branch', 'openEuler-20.03-LTS-SP1')
        }
        return git_src_from_gitee(req_json_para, db, sess_man)
    elif session_function == "release_rpm_source":
        req_json_para = {
            "session_token": session_token,
            "rpm_file_path": request.json.get('rpm_file_path', '').replace('\\', '/').lstrip('/')
        }
        return release_rpm_source(req_json_para, db, sess_man)
    elif session_function == "file_download":
        req_json_para = {
            "session_token": session_token,
            "download_url": request.json.get('download_url', ''),
            "download_name": request.json.get('download_name', '')
        }
        return download_file(req_json_para, db, sess_man)
    elif session_function == "git_spec_from_gitee":
        req_json_para = {
            "session_token": session_token,
            "download_url": request.json.get('download_url', ''),
            "download_name": request.json.get('download_name', '')
        }
        return download_file_spec(req_json_para, db, sess_man)
    elif session_function == "generate_compatibility_report":
        req_json_para = {
            "session_token": session_token,
            "task_koji_link": request.json.get('task_koji_link', ''),
        }
        return generate_compatibility_report(req_json_para, db, sess_man)


@app.route('/get_session_task_by_session_token', methods=['POST'])
def get_session_task_by_session_token():
    session_token = request.json.get('session_token', '')
    session_info_list = sess_man.get_session_info_by_session_token(session_token)
    # print("session_token", session_token, session_info_list)
    msg = msg_template.MsgTemplateForTask()
    msg.set_key_value("session_token", session_token)
    msg.set_key_value("data", session_info_list)
    return msg.get_json()


@app.route('/get_file_list_by_session_token', methods=['POST'])
def get_file_list_by_session_token():
    session_token = request.json.get('session_token', '')
    current_path = request.json.get('current_path', '/').lstrip("/").lstrip("\\")  # TODO 路径校验
    print("current_path", current_path)
    file_list = []
    check_path = os.path.join("static/session", session_token, current_path)
    for path_one in os.listdir(check_path) if os.path.exists(check_path) else []:
        file_list.append({
            "name": path_one,
            "path": os.path.join(current_path, path_one),
            "leaf": not os.path.isdir(os.path.join(check_path, path_one))
        })
    msg = msg_template.MsgTemplateForFileList()
    msg.set_key_value("session_token", session_token)
    msg.set_key_value("data", file_list)
    return msg.get_json()


@app.route('/get_file_tree_by_session_token', methods=['POST'])
def get_file_tree_by_session_token():
    session_token = request.json.get('session_token', '')
    session_path = os.path.join("static/session", session_token)
    print("session_path", session_path)
    file_list = path.get_file_tree_by_base_path(session_path)
    try:
        file_list = path.get_file_tree_by_base_path(session_path)
    except:
        file_list = ["error"]
    msg = msg_template.MsgTemplateForFileList()
    msg.set_key_value("session_token", session_token)
    msg.set_key_value("data", file_list)
    return msg.get_json()


@app.route('/upload_file_by_session_token', methods=['POST'])
def upload_file_by_session_token():
    session_token = request.form.get('session_token', '')
    file_metas = request.files.get('file', None)
    msg = msg_template.MsgTemplateForFileList()
    msg.set_key_value("msg_str", "文件上传失败")
    if file_metas:  # 上传的是文件，通过request接受
        filename = file_metas.filename
        filepath = os.path.join("static/session/", session_token, "file_upload", filename)
        while os.path.exists(filepath):
            filepath += ".r"
        path.dir_init(filepath)  # 初始化目录
        file_metas.save(filepath)
        msg.set_key_value("msg_str", f"文件 [{filename}] 上传成功！")
    msg.set_key_value("session_token", session_token)
    return msg.get_json()


@app.route('/get_koji_pattern_list', methods=['POST'])
def get_koji_pattern_list():
    """
    接口名：从koji中获取列表并进行匹配
    接口协议：POST
    接口路径：/get_koji_pattern_list
    """
    token_session = request.form.get('token_session', '')
    rpm_name = request.form.get('rpm_name', '')
    tag_name = request.form.get('tag_name', '')
    user_token = request.form.get('user_token', '')
    msg = msg_template.MsgTemplateKojiPatternList()
    msg.set_key_value("msg_str", "获取Koji上的任务列表")
    return msg.get_json()


@app.route('/download_file', methods=['get', 'post'])
def download_file():
    """
    接口名：下载
    接口协议：GET
    接口路径：/download_file
    """
    print(request.path)
    print(request.query_string.decode())
    str_request_query = request.query_string.decode()
    # file_path = request.json.get('file_path', 'static/session/202210071912078159/source_gitee/openEuler-20.03-LTS-SP2/vim/vim-8.2.tar.bz2')
    file_path = 'static/session/202210071912078159/source_gitee/openEuler-20.03-LTS-SP2/vim/vim-8.2.tar.bz2'
    file_path = os.path.join('static/session/202210071912078159', str_request_query.split('=')[-1])
    response = make_response(send_file(file_path, as_attachment=True))
    response.headers['filename'] = os.path.basename(file_path)
    response.filename = "aaaa"
    print(response)
    return response


@app.route('/package_dir4rpm', methods=['get', 'post'])
def package_dir4rpm():
    """
    接口名：对目录进行打包，并传到RPM打包服务器上
    接口协议：GET
    接口路径：/package_dir4rpm
    """
    dir_path = request.json.get('dir_path', '')
    session_token = request.json.get('session_token', '')
    dir_path = os.path.join("static/session", session_token, dir_path.lstrip('/').lstrip('\\'))
    # dir_path = 'static/session/202210071912078159/source_gitee/openEuler-20.03-LTS-SP2/vim'
    file_path = f"static/session/202210071912078159/temp4package/{path.get_file_name_random()}.tar.gz"
    path.dir_init(file_path)
    path.compress_tar_gz(dir_path, file_path)
    return {"file_path": os.path.join("temp4package", os.path.basename(file_path))}


@app.route('/package_dir4rpm_axios', methods=['get', 'post'])
def package_dir4rpm_axios():
    """
    接口名：对目录进行打包，并传到RPM打包服务器上
    接口协议：GET
    接口路径：/package_dir4rpm
    """
    dir_path = request.json.get('dir_path', '')
    session_token = request.json.get('session_token', '')
    dir_path = os.path.join("static/session", session_token, dir_path.lstrip('/').lstrip('\\'))
    # dir_path = 'static/session/202210071912078159/source_gitee/openEuler-20.03-LTS-SP2/vim'
    file_path = f"static/session/202210071912078159/temp4package/{path.get_file_name_random()}"
    path.dir_init(file_path)
    path.compress_tar_gz(dir_path, file_path)
    # return {"file_path": os.path.join("temp4package", os.path.basename(file_path))}

    response = make_response(send_file(file_path, as_attachment=True))
    response.headers['filename'] = os.path.basename(file_path)
    response.headers['filepath'] = file_path
    print(response)
    return response


CORS(app, resources=r'/*')
if __name__ == "__main__":
    app.run(debug=True, host='0.0.0.0', port=8091)  # 运行app
